#include "HashBucket.hpp"
#include <vector>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <iostream>
#include <time.h>


//void test1(){
//  HashTable<int,int> ht;
//  int arr[] = {1,11,4,15,26,7,44,7};
//  for(auto e : arr)
//  {
//    ht.insert(make_pair(e,e));
//  }
//  ht.printHT();
//  ht.insert(make_pair(9,9));
//  ht.printHT();
//  ht.erase(4);
//  cout << ht.find(44) << endl;
//  cout << ht.find(4) << endl;
//  ht.insert(make_pair(-2,-2));
//  ht.printHT();
//  cout << ht.find(-2) << endl;
//}

void test2(){
  HashTable<string, int> counter;
  string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉"};
  //方法一：上一章讲过的方法
  for(string &e : arr)
  {
    auto ret = counter.find(e);
    if(ret)
    {
      ++ret->_kv.second; 
    } 
    else{
      counter.insert(make_pair(e,1));                                                                                           }
  }
  counter.printHT();
}

void test3(){
  srand(time(nullptr));
  const size_t NUM = 1000;
  HashTable<int, int> ht;
  for(size_t i=0; i<NUM; ++i)
  {
    int num = rand()+i;
    ht.insert(make_pair(num, num));
  }
  cout << "数据个数：" << ht.size() << endl;
  cout << "表的长度：" << ht.table_size() << endl;
  cout << "桶的个数：" << ht.bucket_count() << endl;
  cout << "平均每个桶的长度：" << (double)ht.size() / ht.bucket_count() << endl;
  cout << "最长桶的长度：" << ht.max_bucket_len() << endl;
  cout << "载荷因子：" << (double)ht.size() / ht.table_size() << endl;
}

void test4(){
  srand(time(nullptr));
  const size_t NUM = 1000000;
  set<int> s;
  unordered_set<int> us;
  vector<int> tmp;
  tmp.reserve(NUM);
  for(size_t i=0; i<NUM; ++i)
  {
    int num = rand();
    tmp.push_back(num);
  }

  cout << "data_size: " << NUM << endl;
  clock_t begin1, end1, begin2, end2;
  //对比插入
  begin1 = clock();
  for(auto e : tmp)
  {
    s.insert(e);
  }
  end1 = clock();

  begin2 = clock();
  for(auto e : tmp)
  {
    us.insert(e);
  }
  end2 = clock();
  
  cout << "set::insert: " << (double)(end1-begin1)/CLOCKS_PER_SEC*1000 << endl;
  cout << "unordered_set::insert: " << (double)(end2-begin2)/CLOCKS_PER_SEC*1000 << endl;

  //对比查找
  begin1 = clock();
  for(auto e : tmp)
  {
    s.find(e);
  }
  end1 = clock();

  begin2 = clock();
  for(auto e : tmp)
  {
    us.find(e);
  }
  end2 = clock();
  cout << "set::find: " << (double)(end1-begin1)/CLOCKS_PER_SEC*1000 << endl;
  cout << "unordered_set::find: " << (double)(end2-begin2)/CLOCKS_PER_SEC*1000 << endl;

  //对比删除
  begin1 = clock();
  for(auto e : tmp)
  {
    s.erase(e);
  }
  end1 = clock();

  begin2 = clock();
  for(auto e : tmp)
  {
    us.erase(e);
  }
  end2 = clock();
  cout << "set::earse: " << end1-begin1 << endl;
  cout << "unordered_set::erase: " << end2-begin2 << endl;
}

void test_op()
{
	int n = 10000000;
	vector<int> v;
	v.reserve(n);
	srand(time(0));
	for (int i = 0; i < n; ++i)
	{
		//v.push_back(i);
		v.push_back(rand()+i);  // ظ
		//v.push_back(rand());  // ظ
	}

	size_t begin1 = clock();
	set<int> s;
	for (auto e : v)
	{
		s.insert(e);
	}
	size_t end1 = clock();

	size_t begin2 = clock();
	unordered_set<int> us;
	for (auto e : v)
	{
		us.insert(e);
	}
	size_t end2 = clock();

	cout <<"size:"<<s.size() << endl;

	cout << "set insert:" << (double)(end1 - begin1)/CLOCKS_PER_SEC*1000 << endl;
	cout << "unordered_set insert:" << (double)(end2 - begin2)/CLOCKS_PER_SEC*1000 << endl;


	size_t begin3 = clock();
	for (auto e : v)
	{
		s.find(e);
	}
	size_t end3 = clock();

	size_t begin4 = clock();
	for (auto e : v)
	{
		us.find(e);
	}
	size_t end4 = clock();
	cout << "set find:" << (double)(end3 - begin3)/CLOCKS_PER_SEC*1000 << endl;
	cout << "unordered_set find:" << (double)(end4 - begin4)/CLOCKS_PER_SEC*1000 << endl;


	size_t begin5 = clock();
	for (auto e : v)
	{
		s.erase(e);
	}
	size_t end5 = clock();
	cout << "set erase" << endl;

	size_t begin6 = clock();
	for (auto e : v)
	{
		us.erase(e);
	}
	size_t end6 = clock();
	cout << "unordered_set erase" << endl;

	cout << "set erase:" << (double)(end5 - begin5)/CLOCKS_PER_SEC*1000 << endl;
	cout << "unordered_set erase:" << (double)(end6 - begin6)/CLOCKS_PER_SEC*1000 << endl;

	unordered_map<string, int> countMap;
	countMap.insert(make_pair("ƻ", 1));
}

int main(){
  //test2();
  test3();
  //test4();
  //test_op();
  return 0;
}
